#include <../include/middleWare/CORS/CorsMiddleware.hpp>
#include <muduo/base/Logging.h>
#include <sstream>
using namespace http::middleWare;

CorsMiddleware::CorsMiddleware(const CorsConfig &config) : config(config) {}

void CorsMiddleware::before(const HttpRequest &request)
{
    LOG_DEBUG << "CorsMiddleware::before";//打印日志
    if (request.getMethod() == HttpRequest::Method::Options)
    {
        //处理预检请求
        LOG_INFO << "CorsMiddleware::before handlePreflight";
        HttpResponse response;
        handlePreflight(request, response);
        throw response;//对于OPTIONS预检请求，直接抛出响应对象
        //利用异常机制实现早期返回，避免预检请求进入业务逻辑处理流程
    }
    else
    {
        //处理正常请求
        LOG_INFO << "CorsMiddleware::before handleNormalRequest";
    }
}

void CorsMiddleware::after(HttpResponse &response)
{
    LOG_DEBUG << "CorsMiddleware::after";//打印日志
    //添加CORS响应头
    if(!config.allowedOrigins.empty())
    {
        //如果允许的源不为空，则添加CORS响应头
        if(std::find(config.allowedOrigins.begin(), config.allowedOrigins.end(), "*")!=config.allowedOrigins.end())
        {
            addCorsHeaders(response,"*");//*表示允许所有源
        }
        else
        {
            addCorsHeaders(response,config.allowedOrigins[0]);//默认使用第一个源
        }
    }
}

bool CorsMiddleware::isOriginAllowed(const std::string &origin) const
{

    return config.allowedOrigins.empty() || 
    std::find(config.allowedOrigins.begin(), config.allowedOrigins.end(), origin) != config.allowedOrigins.end()||
    std::find(config.allowedOrigins.begin(), config.allowedOrigins.end(), "*") != config.allowedOrigins.end();//*表示允许所有源
}

void CorsMiddleware::handlePreflight(const HttpRequest &request, HttpResponse &response)
{
    //处理预检请求
    const std::string origin = request.getHeader("Origin");
    if(!isOriginAllowed(origin)){
        LOG_WARN << "CorsMiddleware::handlePreflight origin not allowed";
        response.setStatusCode(HttpResponse::Forbidden);
        return;
    }
    addCorsHeaders(response,origin);//添加CORS响应头
    response.setStatusCode(HttpResponse::NoContent);
    LOG_INFO << "Preflight request processed successfully";
}

void CorsMiddleware::addCorsHeaders(HttpResponse &response,const std::string &origin)
{
    try
    {
        response.addHeader("Access-Control-Allow-Origin", origin);
        if(config.allowCredentials)
        {
            response.addHeader("Access-Control-Allow-Credentials", "true");
        }
        
        if(!config.allowedMethods.empty())
        {
            response.addHeader("Access-Control-Allow-Methods", join(config.allowedMethods, ","));
        }
        if(!config.allowedHeaders.empty())
        {
            response.addHeader("Access-Control-Allow-Headers", join(config.allowedHeaders, ","));
        }
        if(config.maxAge > 0)
        {
            response.addHeader("Access-Control-Max-Age", std::to_string(config.maxAge));
        }
    }
    catch(const std::exception& e)
    {
        LOG_ERROR << "CorsMiddleware::addCorsHeaders error: " << e.what();
    }
    LOG_INFO << "CORS headers added successfully";
}

std::string CorsMiddleware::join(const std::vector<std::string> &strings, const std::string &delimiter)
{
    std::stringstream ss;
    for(size_t i = 0; i < strings.size(); ++i)
    {
        if(i > 0)//如果不是第一个元素，则添加分隔符
        {
            ss << delimiter;
        }
        ss << strings[i];
    }
    return ss.str();
}